package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.AuthStatusEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.jetcache.utils.JetCacheUtils;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.constants.BaseCache;
import com.bifang.module.base.core.helper.DictHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.enums.EduSynDyApplyDictEnum;
import com.jwsoft.manager.common.enums.EnrollStatusFormalEnum;
import com.jwsoft.manager.common.vo.common.AreaControlVO;
import com.jwsoft.manager.common.vo.eduDyjyQuerySync.DySyncResult;
import com.jwsoft.manager.common.vo.eduSyncDyApprove.EduSyncDyApproveKeyVO;
import com.jwsoft.manager.common.vo.eduSyncDyApprove.EduSyncDyApproveQueryVO;
import com.jwsoft.manager.common.vo.eduSyncDyApprove.EduSyncDyApproveVO;
import com.jwsoft.manager.core.dao.model.EduStudentEnroll;
import com.jwsoft.manager.core.dao.model.EduSyncDyApply;
import com.jwsoft.manager.core.dao.model.EduSyncDyApprove;
import com.jwsoft.manager.core.dao.service.EduStudentEnrollService;
import com.jwsoft.manager.core.dao.service.EduSyncDyApplyService;
import com.jwsoft.manager.core.dao.service.EduSyncDyApproveService;
import com.jwsoft.manager.core.integration.EduSyncDyApproveIntegration;
import com.jwsoft.manager.core.util.EduHelper;
import com.jwsoft.manager.core.util.dySync.CallUtils;
import com.jwsoft.manager.core.util.dySync.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.Duration;
import java.util.*;
/**
 * 东阳市报名专库同步情况表业务实现类
 *
 * @author wangt
 * @since 2024-06-11
 */
@ApiService(funcCode = "eduSyncDyApprove", title = "东阳市报名专库同步情况表")
public class EduSyncDyApproveIntegrationImpl implements EduSyncDyApproveIntegration {

    @Autowired
    public EduSyncDyApproveService eduSyncDyApproveService;
    @Autowired
    private EduHelper eduHelper;
    @Autowired
    private RedisHelper redisHelper;
    @Autowired
    private EduStudentEnrollService eduStudentEnrollService;
    @Autowired
    private EduSyncDyApplyService eduSyncDyApplyService;

    @Autowired
    private DictHelper dictHelper;

    @Autowired
    private EduDyjyQuerySyncIntegrationImpl dyjyQuerySyncIntegration;

    @Autowired
    private CallUtils callUtils;

    @Override
    @OpApi(funcCode = "eduSyncDyApprove0001", title = "东阳市报名专库同步情况表分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduSyncDyApproveVO> getList(EduSyncDyApproveQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        QueryWrapper<EduSyncDyApprove> eduSyncDyApproveQueryWrapper = new QueryWrapper<>();
        eduSyncDyApproveQueryWrapper.lambda()
                .eq(!ObjectUtils.isEmpty(vo.getYear()),EduSyncDyApprove::getYear,vo.getIdcard())
                .eq(StringUtils.isNotBlank(vo.getIdcard()),EduSyncDyApprove::getIdcard,vo.getIdcard());
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        List<EduSyncDyApprove> list = eduSyncDyApproveService.list(eduSyncDyApproveQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduSyncDyApprove> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduSyncDyApproveVO> resultList = Convert.toList(EduSyncDyApproveVO.class, pageInfo.getList());
        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduSynDyApplyDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduSyncDyApprove0002", title = "东阳市报名专库同步情况表根据主键查询详情", funcType = FuncTypeEnum.query,checkPrivilege = BoolEnum.FALSE)
    public EduSyncDyApproveVO getById(EduSyncDyApproveKeyVO vo) {
        EduSyncDyApprove entity = eduSyncDyApproveService.getById(vo.getJhApproveId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduSyncDyApproveVO result = Convert.convert(EduSyncDyApproveVO.class, entity);
        return result;
    }
    /** 保存前统一校验*/
    @Override
    @OpApi(funcCode = "eduSyncDyApprove0003", title = "东阳市报名专库同步情况表保存前校验", funcType = FuncTypeEnum.other ,checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduSyncDyApproveVO vo) {
        //主键为空为新增校验
        if (StringUtils.isEmpty(vo.getIdcard())) {
            throw new AppException("身份证不能为空");
        }
        // 设置默认年份
        if (ObjectUtils.isEmpty(vo.getYear())) {
            vo.setYear(eduHelper.thisYear());
        }
        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "eduSyncDyApprove0004", title = "东阳市报名专库同步情况表新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduSyncDyApprove0004",
            operationName = "东阳市报名专库同步情况表新增",
            dataType = "jhApproveId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSyncDyApproveVO add(EduSyncDyApproveVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduSyncDyApprove entity = Convert.convert(EduSyncDyApprove.class, vo);
        eduSyncDyApproveService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setJhApproveId(entity.getJhApproveId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSyncDyApprove0005", title = "东阳市报名专库同步情况表修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduSyncDyApprove0005",
            operationName = "东阳市报名专库同步情况表修改",
            dataType = "jhApproveId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSyncDyApproveVO edit(EduSyncDyApproveVO vo) {
        if (ObjectUtils.isEmpty(vo.getJhApproveId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduSyncDyApprove oldEntity = eduSyncDyApproveService.getById(vo.getJhApproveId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduSyncDyApprove entity = Convert.convert(EduSyncDyApprove.class, vo);
        eduSyncDyApproveService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSyncDyApprove0006", title = "东阳市报名专库同步情况表根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduSyncDyApprove0006",
            operationName = "东阳市报名专库同步情况表删除",
            dataType = "jhApproveId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduSyncDyApproveKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getJhApproveId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduSyncDyApprove entity = eduSyncDyApproveService.getById(vo.getJhApproveId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduSyncDyApproveService.removeById(vo.getJhApproveId());
    }

    @Override
    @OpApi(funcCode = "eduSyncDyApprove0007", title = "批量生成同步金华库审核数据", funcType = FuncTypeEnum.query)
    public void addBatch(EduSyncDyApproveVO vo) {
        String redisKey="dyedu:syncDyApprove:batch";
        if(redisHelper.hasKey(redisKey)){
            throw new AppException("正在批量处理中......");
        }
        redisHelper.set(redisKey,"1",1800);
        try {
            if (vo.getAllFlag()==null){
                vo.setAllFlag(false);
            }
            String areaCode=vo.getApplyCountyCode();
            if(StringUtils.isBlank(areaCode)){
                areaCode= SessionUtil.getAreaCode();
            }
            if(StringUtils.isBlank(areaCode)){
                areaCode=eduHelper.thisAreaCode();
            }
            Integer year=eduHelper.thisYear();
            List<String> enrollStatusList=new ArrayList<>();
            enrollStatusList.add(EnrollStatusFormalEnum.lq.getType());
            LambdaQueryWrapper<EduStudentEnroll> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.select(EduStudentEnroll::getFullName,EduStudentEnroll::getIdcard,EduStudentEnroll::getYear,
                    EduStudentEnroll::getAreaCode,EduStudentEnroll::getSchoolNature,
                    EduStudentEnroll::getSex,EduStudentEnroll::getHouseholdPlace,EduStudentEnroll::getCardType,
                    EduStudentEnroll::getSchoolCategory,EduStudentEnroll::getCreateTime,EduStudentEnroll::getBirthYmd,
                    EduStudentEnroll::getAddress,EduStudentEnroll::getFatherName,
                    EduStudentEnroll::getAuthStatus,EduStudentEnroll::getAuthRemarks,EduStudentEnroll::getAuthTime,
                    EduStudentEnroll::getMotherName,EduStudentEnroll::getAuthUserId).eq(EduStudentEnroll::getAreaCode,areaCode)
                    .eq(EduStudentEnroll::getYear,year)
                    .in(EduStudentEnroll::getEnrollStatus,enrollStatusList)
                    .inSql(EduStudentEnroll::getIdcard,"select idcard from edu_sync_dy_apply where year="+year+" and del='0' ");
            if(vo.getAllFlag()){
                queryWrapper.notInSql(EduStudentEnroll::getIdcard,"select idcard from edu_sync_dy_approve where year="+year+" and del='0' ");
            }

            List<EduStudentEnroll> list=eduStudentEnrollService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(list)){
                Long importBatchId= IdWorker.getId();
                Map<String,String> map=new HashMap<>();
                for (EduStudentEnroll eduStudentEnroll:list){
                    if (map.containsKey(eduStudentEnroll.getIdcard())){
                        continue;
                    }
                    map.put(eduStudentEnroll.getIdcard(),eduStudentEnroll.getFullName());
                    EduSyncDyApprove eduSyncDyApprove=new EduSyncDyApprove();
                    QueryWrapper<EduSyncDyApprove> approveQueryWrapper=new QueryWrapper<>();
                    approveQueryWrapper.lambda().select(EduSyncDyApprove::getJhApplyId,EduSyncDyApprove::getJhApproveId).eq(EduSyncDyApprove::getIdcard,eduStudentEnroll.getIdcard())
                            .eq(EduSyncDyApprove::getYear,eduStudentEnroll.getYear())
                            .eq(EduSyncDyApprove::getApplyCountyCode,eduStudentEnroll.getAreaCode());
                    List<EduSyncDyApprove> approveList=eduSyncDyApproveService.list(approveQueryWrapper);
                    if (!CollectionUtils.isEmpty(approveList)){
                        eduSyncDyApprove.setJhApproveId(approveList.get(0).getJhApproveId());
                    }
                    QueryWrapper<EduSyncDyApply> applyQueryWrapper=new QueryWrapper<>();
                    applyQueryWrapper.lambda().select(EduSyncDyApply::getJhApplyId).eq(EduSyncDyApply::getIdcard,eduStudentEnroll.getIdcard())
                            .eq(EduSyncDyApply::getYear,eduStudentEnroll.getYear())
                            .eq(EduSyncDyApply::getApplyCountyCode,eduStudentEnroll.getAreaCode());
                    List<EduSyncDyApply> applyList=eduSyncDyApplyService.list(applyQueryWrapper);
                    if (!CollectionUtils.isEmpty(applyList)){
                        eduSyncDyApprove.setJhApplyId(applyList.get(0).getJhApplyId());
                    }
                    eduSyncDyApprove.setAuditSyncFlag("0");
                    eduSyncDyApprove.setApproveHuman(eduStudentEnroll.getAuthUserId());
                    eduSyncDyApprove.setYear(eduStudentEnroll.getYear());
                    eduSyncDyApprove.setApproveTime(eduStudentEnroll.getAuthTime());
                    eduSyncDyApprove.setName(eduStudentEnroll.getFullName());
                    eduSyncDyApprove.setCardType(eduStudentEnroll.getCardType());
                    eduSyncDyApprove.setIdcard(eduStudentEnroll.getIdcard());
                    eduSyncDyApprove.setImportBatchId(importBatchId);
                    if (AuthStatusEnum.YES.getType().equalsIgnoreCase(eduStudentEnroll.getAuthStatus())) {
                        eduSyncDyApprove.setApproveState("1");
                    } else {
                        eduSyncDyApprove.setApproveState("2");
                    }
                    eduSyncDyApprove.setSchoolCategory(eduStudentEnroll.getSchoolCategory());
                    eduSyncDyApprove.setApplyCountyCode(eduStudentEnroll.getAreaCode());
                    eduSyncDyApprove.setApproveOpinion(eduStudentEnroll.getAuthRemarks());
                    eduSyncDyApprove.setApproveHuman(eduStudentEnroll.getAuthUserId());
                    eduSyncDyApproveService.saveOrUpdate(eduSyncDyApprove);
                }
            }
        } catch (Exception e) {
            throw new AppException("批量生成同步到金华审核库数据系统异常" + e.getMessage(), e);
        } finally {
            redisHelper.del(redisKey);
        }

    }

    private void saveSyncStudentApproveInfo(EduSyncDyApprove vo) {


        Map<String, Object> params = BeanUtil.beanToMap(vo, false, true);

        //map转string
        String paramsStr = JsonUtil.toJsonString(params);
        //将传入参数 进行签名
        String timestamp = String.valueOf(System.currentTimeMillis());
        //参数进行加密
        String appKey = dyjyQuerySyncIntegration.getCommon("dy_sync_appKey");
        String encrypt = callUtils.encrypt(paramsStr, appKey);
        //根据参数，密钥，时间生成签名
        String appSecret = dyjyQuerySyncIntegration.getCommon("dy_sync_appSecret");


        String accessToken = "";
        //调用获取token方法，得到token信息
        Cache<String, String> tokenCache = JetCacheUtils.create(BaseCache.CACHE_ACCESS_TOKEN_CLIENT, CacheType.BOTH, Duration.ofSeconds(1500L), Duration.ofSeconds(60));
        String redisKey = vo.getApplyCountyCode() + vo.getYear();
        accessToken = tokenCache.get(redisKey);
        if (StringUtils.isBlank(accessToken)) {
            //调用获取token方法，得到token信息
            DySyncResult token = dyjyQuerySyncIntegration.getToken();
            accessToken = (String) token.getData().get("accessToken");
            tokenCache.put(redisKey, accessToken);
        }
        if (StringUtils.isBlank(accessToken)) {
            throw new AppException("accessToken不能为空");
        }
        //加密传参
        HashMap<String, String> map = new HashMap<>();
        map.put("cryptoStr", encrypt);
        String cryptoStr = JSONObject.toJSONString(map);
        String signature = callUtils.getSign(cryptoStr, appSecret, timestamp);
        if (StringUtils.isBlank(signature)) {
            throw new AppException("签名不能为空");
        }
        //调用同步删除接口
        String reqUrl = dyjyQuerySyncIntegration.getCommon("dy_sync_reqUrl");
        String appId = dyjyQuerySyncIntegration.getCommon("dy_sync_appId");
        String url = reqUrl + "syncSaveJhApprove0001";
        String data = encrypt;
        HttpResponse execute = HttpRequest.post(url)
                //设置请求体
                .header("Content-Type", "application/json")
                .header("signature", signature)
                .header("timestamp", timestamp)
                .header("accessToken", accessToken)
                .header("appId", appId)
                .setReadTimeout(10000)
                .body(cryptoStr) //加密
                .execute();
        String body = execute.body();
        if (StringUtils.isBlank(body)) {
            throw new AppException("请求接口失败失败，未返回信息");
        }
        JSONObject jsonBody = JSONObject.parseObject(body);
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getInteger("code") != 0) {
                if ("401".equals(jsonObject.getString("code")) || "456".equals(jsonObject.getString("code"))) {
                    //调用获取token方法，得到token信息
                    DySyncResult token = dyjyQuerySyncIntegration.getToken();
                    accessToken = (String) token.getData().get("accessToken");
                    tokenCache.put(redisKey, accessToken);
                } else {
                    String errorMessage = (String) jsonObject.get("message");
                    throw new AppException("错误原因：" + errorMessage);
                }
            }
        } catch (AppException e) {
            throw new AppException(e.getMsg());
        } catch (Exception e) {
            throw new AppException("请求接口失败失败：" + body);
        }
        //密文
        String encryptResult = (String) jsonObject.get("result");
        if (StringUtils.isNotBlank(encryptResult)) {
            //对密文进行解密
            String decryptResult = callUtils.decrypt(encryptResult, appSecret);
            //解密后的密文转json
            JSONObject jsoncontent = JSONObject.parseObject(decryptResult);
            //转换json
            jsonBody.put("result", jsoncontent);
        }
    }

    @Override
    public int eduJhjyShSync(AreaControlVO vo) {
        String redisKey="dyedu:syncDyApprove:batchSync";
        if(redisHelper.hasKey(redisKey)){
            throw new AppException("正在批量同步金华审核数据处理中......");
        }
        redisHelper.set(redisKey,"1",1800);
        Integer year=eduHelper.thisYear();
        if (StringUtils.isBlank(vo.getAreaCode())){
            vo.setAreaCode(eduHelper.thisAreaCode());
        }
        QueryWrapper<EduSyncDyApprove> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduSyncDyApprove::getYear, year)
                .eq(EduSyncDyApprove::getApplyCountyCode,vo.getAreaCode())
                .eq(EduSyncDyApprove::getAuditSyncFlag,BoolEnum.FALSE.getType());
        List<EduSyncDyApprove> list=eduSyncDyApproveService.list(queryWrapper);

        if (CollectionUtils.isEmpty(list)){
            QueryWrapper<EduSyncDyApprove> queryWrapperError = new QueryWrapper<>();
            queryWrapperError.lambda().eq(EduSyncDyApprove::getYear, year)
                    .eq(EduSyncDyApprove::getApplyCountyCode,vo.getAreaCode())
                    .eq(EduSyncDyApprove::getAuditSyncFlag,"2");
            List<EduSyncDyApprove> errorList=eduSyncDyApproveService.list(queryWrapperError);
            if(CollectionUtils.isEmpty(errorList)){
                redisHelper.del(redisKey);
                return 0;
            }
            list=errorList;
        }
        int i=0;
        for(EduSyncDyApprove approve:list){
            try {
                saveSyncStudentApproveInfo(approve);
                approve.setAuditSyncFlag("1");
                approve.setAuditSyncRemark("成功");
                eduSyncDyApproveService.updateById(approve);
                i++;
            }catch (AppException e){
                approve.setAuditSyncFlag("2");
                String msg=e.getMsg();
                if (StringUtils.isNotBlank(msg)&&msg.length()>300){
                    msg=msg.substring(0,300);
                }
                approve.setAuditSyncRemark(msg);
                eduSyncDyApproveService.updateById(approve);
            }catch (Exception e){
                approve.setAuditSyncFlag("2");
                String msg=e.getMessage();
                if (StringUtils.isNotBlank(msg)&&msg.length()>300){
                    msg=msg.substring(0,300);
                }
                approve.setAuditSyncRemark(msg);
                eduSyncDyApproveService.updateById(approve);
            }

        }
        redisHelper.del(redisKey);
        return i;
    }
}
